package com.fingard.dsp.bank.directbank.swiftpass01;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.TreeMap;

import com.fingard.common.utils.json.JSONUtils;
import com.fingard.crypto.DigestHelper;
import com.fingard.dsp.bank.directbank.DirectBase;
import com.fingard.net.WebRequest;
import com.fingard.text.StringHelper;
import com.fingard.util.DateHelper;
import com.fingard.xml.XElement;
import com.fingard.xml.XmlTextReader;

public class SwiftPass01Base extends DirectBase {
    protected String getCharset() {
        return getBankConfig().getCharset("UTF-8");
    }

    protected String get_nonce_str() throws Exception {
        String time_stamp = DateHelper.getSecsFrom1970();
        Random random = new Random();
        long randLong = random.nextLong();
        randLong = random.nextLong();
        String nonce_str = time_stamp + String.format("%20d", randLong);
        nonce_str = DigestHelper.cryptoMD5RetHexStr(nonce_str.getBytes());
        return nonce_str;
    }

    protected HashMap<String, String> getOpenid(String p_appId, String p_appSecret, String p_code) {
        HashMap<String, String> retHash = new HashMap<String, String>();
        String respCode = "";
        String respInfo = "";
        String tmpUrl = bankFront.getUrl("access_token");
        if (StringHelper.isNullOrEmpty(tmpUrl)) {
            respCode = "-1";
            respInfo = "未设置“通过code换取网页授权access_token”的地址";
        } else {
            tmpUrl = tmpUrl + "?appid=" + p_appId + "&secret=" + p_appSecret + "&code=" + p_code + "&grant_type=authorization_code";
            this.WriteBankLogStep2(tmpUrl);
            WebRequest tmpWebRequest = new WebRequest(tmpUrl);
            String[] tmpRet = tmpWebRequest.upload(null, this.getCharset());
            if (tmpRet[0].length() == 0) {
                this.WriteBankLogStep3(tmpRet[1]);
                if (tmpRet[1].startsWith("{")) {
                    retHash = JSONUtils.json2Map(tmpRet[1]);
                    respCode = "0";
                } else {
                    respCode = "-1";
                    respInfo = tmpRet[1];
                }
            } else {
                this.WriteBankLogLn(tmpRet[0] + "\r\n" + tmpRet[1]);
                respCode = "-1";
                respInfo = tmpRet[1];
            }
        }
        retHash.put("RespCode", respCode);
        retHash.put("RespInfo", respInfo);
        return retHash;
    }

    public String signMessage(HashMap<String, String> p_mapParams, String p_saltKey) throws Exception {

        TreeMap<String, String> treeMap = new TreeMap<String, String>();
        for (Map.Entry<String, String> entry : p_mapParams.entrySet()) {
            String name = entry.getKey();
            String value = entry.getValue();
            if (StringHelper.hasAnyChar(value)) {
                treeMap.put(name, value);
            }
        }
        StringBuilder sbValues = new StringBuilder();
        for (String key : treeMap.keySet()) {
            if (sbValues.length() > 0) {
                sbValues.append("&");
            }
            sbValues.append(key + "=" + treeMap.get(key));
        }
        sbValues.append("&key=" + p_saltKey);
        byte[] tmpDataBytes = sbValues.toString().getBytes(getCharset());
        return DigestHelper.cryptoMD5RetHexStr(tmpDataBytes).toUpperCase();
    }

    public String buildXml(HashMap<String, String> p_mapParams) {

        StringBuilder sbXml = new StringBuilder();
        sbXml.append("<xml>\r\n");
        for (Map.Entry<String, String> entry : p_mapParams.entrySet()) {
            String name = entry.getKey();
            String value = entry.getValue();
            if (StringHelper.hasAnyChar(value)) {
                sbXml.append("  <" + name + "><![CDATA[" + value + "]]></" + name + ">\r\n");
            }
        }
        sbXml.append("</xml>");

        return sbXml.toString();
    }

    public boolean verifySign(String p_xml, String p_saltKey, StringBuilder p_sb) throws Exception {
        XmlTextReader tmpBkReader = loadBankRespXmlReader(p_xml, p_sb);
        if (tmpBkReader != null) {
            if (tmpBkReader.read("/xml")) {
                ArrayList<XElement> tmpList = tmpBkReader.readedXElement.getAllChildList();
                if (tmpList != null && tmpList.size() > 0) {
                    String chkSign = "";

                    HashMap<String, String> respParams = new HashMap<String, String>();
                    for (int i = 0; i < tmpList.size(); i++) {
                        XElement xe = tmpList.get(i);
                        if (xe.name.equals("sign")) {
                            chkSign = xe.innerText;
                        } else if (StringHelper.hasAnyChar(xe.innerText)) {
                            respParams.put(xe.name, xe.innerText);
                        }
                    }

                    String sign = this.signMessage(respParams, p_saltKey);
                    if (sign.equals(chkSign)) {
                        return true;
                    } else {
                        p_sb.append("验签失败");
                        return false;
                    }
                } else {
                    p_sb.append("用于验签的xml节点为空");
                    return false;
                }
            } else {
                p_sb.append("用于验签的xml节点为空");
                return false;
            }
        } else {
            return false;
        }
    }

    protected String[] sendToBank(String p_reqStr, String p_for) throws Exception {
        String[] retStr = new String[]{"", ""};
        String url = bankFront.getUrl(p_for);
        WriteBankUrlLogLn(url);
        WriteBankLogStep2(p_reqStr);
        WebRequest tmpWebRequest = new WebRequest(url);
        int timeout = 10000;
        if ("downloadbill".equals(p_for)) {
            timeout = getReadTimeout(60);
        } else {
            timeout = getReadTimeout(15);
        }
        //tmpWebRequest.setConnectTimeout(timeout);
        tmpWebRequest.setReadTimeout(timeout);
        tmpWebRequest.setRequestProperty("Content-Type", "text/xml;charset=ISO-8859-1");
        tmpWebRequest.setRequestProperty("connection", "Close");
        byte[] tmpUpBytes = p_reqStr.getBytes(getCharset());
        retStr = tmpWebRequest.upload(tmpUpBytes, getCharset());
        WriteBankLogStep3(retStr[1]);
        if (retStr[0].length() == 0) {
            int tmpIndex = retStr[1].indexOf("<");
            if (tmpIndex > 0) {
                retStr[1] = retStr[1].substring(tmpIndex);
            }
        }

        return retStr;
    }

}
